using BuildingBlocks.Core.Entities;
using Identity.Domain.Exceptions;

namespace Identity.Domain.Aggregates;

public sealed class Role : AggregateRoot<Guid>
{
    public string Code { get; private set; }
    public string Name { get; private set; }
    public string? Description { get; private set; }
    public bool Status { get; private set; }=false;
    private readonly List<Guid> _permissionIds = new();

    public IReadOnlyCollection<Guid> PermissionIds => _permissionIds.AsReadOnly();
    private Role() { }
    public static Role CreateRole(string code, string? name, string? description = "", bool status = false)
    {
        if (string.IsNullOrWhiteSpace(code)) throw new DomainException("code 不能为空");
        return new Role()
        {
            Code = code,
            Name = string.IsNullOrWhiteSpace(name)?code:name,
            Description = description,
            Status = status
        };
    }
    public void AddPermission(Guid permissionId)
    {
        if (_permissionIds.Any(x => x == permissionId)) return;
        _permissionIds.Add(permissionId);
    }

    public void RemovePermission(Guid permissionId)
    {
        if (!_permissionIds.Any(x => x == permissionId)) return;
        
        _permissionIds.Remove(permissionId);
    }

    public void ChangeName(string newName)
    {
        if (string.IsNullOrWhiteSpace(newName))
            throw new DomainException("Role name is required.");
        if (newName == Name) return;

        Name = newName;
    }
    public void ChangeCode(string newCode)
    {
        if (string.IsNullOrWhiteSpace(newCode))
        {
            throw new DomainException("Role code is required");
        }
        if (newCode == Name) return;
    }

    public void ChangeDescription(string? newDescription)
    {
        Description = newDescription;
    }



    // 从持久化状态加载（不会校验唯一性）
    public static Role LoadFromPersistence(Guid id, string code, string name, IEnumerable<Guid> permissionIds, string description, bool status)
    {
        var role = new Role
        {
            Id = id,
            Code = code,
            Name = name,
            Description = description,
            Status = status
        };
        role._permissionIds.AddRange(permissionIds);

        return role;
    }
}